package com.tencent.cloud.iov.util;

import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

/**
 * RSA加解密工具类
 *
 * @author vinsonhuang
 * @date 2018/5/22
 */
public class RSAUtils {

    private static final String TAG = RSAUtils.class.getSimpleName();

    public static final String ACCOUNT_RSA_PUBLIC_KEY = "account_rsa_public_key";

    public static final String PROFILE_RSA_PUBLIC_KEY = "profile_rsa_public_key";

    private static final String TRANS_FORMATION = "RSA/ECB/OAEPwithSHA-256andMGF1Padding";

    private static final String ALGORITHM = "RSA";

    private static final String CHARSET = "UTF-8";

    /**
     * 公钥加密
     *
     * @param publicKey 公钥
     * @param data      待加密数据
     * @return String 加密数据
     */
    public static String encryptData(String publicKey, String data) {
        String encryptInfo = "";
        if (TextUtils.isEmpty(data) || TextUtils.isEmpty(publicKey)) {
            return encryptInfo;
        }
        String pubKey = handlePublicKey(publicKey);
        byte[] publicKeyBytes = Base64.decode(pubKey, Base64.NO_WRAP);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory;
        try {
            keyFactory = KeyFactory.getInstance(ALGORITHM);
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
            byte[] encryptData = cipher.doFinal(data.getBytes());
            encryptInfo = Base64.encodeToString(encryptData, Base64.NO_WRAP);
        } catch (Exception e) {
            Log.e(TAG, "encrypt data failed", e);
        }

        return encryptInfo;
    }

    /**
     * 私钥解密
     *
     * @param privateKey 私钥
     * @param data       经过encryptedData()加密的数据
     * @return
     */
    public static String decryptData(String privateKey, String data) {
        String decryptInfo = "";
        if (TextUtils.isEmpty(data) || TextUtils.isEmpty(privateKey)) {
            return decryptInfo;
        }
        try {
            byte[] privateKeyBytes = Base64.decode(privateKey, Base64.NO_WRAP);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            PrivateKey rsaPrivateKey = keyFactory.generatePrivate(x509KeySpec);
            Cipher cipher = Cipher.getInstance(TRANS_FORMATION);
            cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
            byte[] decryptData = cipher.doFinal(data.getBytes(CHARSET));
            decryptInfo = Base64.encodeToString(decryptData, Base64.NO_WRAP);
        } catch (Exception e) {
            Log.e(TAG, "decrypt data failed", e);
        }

        return decryptInfo;
    }

    /**
     * 处理加密公钥
     *
     * @param publicKey
     */
    private static String handlePublicKey(String publicKey) {
        return publicKey.replace("-----BEGIN PUBLIC KEY-----\n", "")
                .replace("-----END PUBLIC KEY-----", "");
    }
}
